﻿using System;
using System.Net;
using System.IO;
using System.Security.Cryptography.X509Certificates;
using System.Net.Security;
using System.Text;
using System.Collections.Specialized;
using System.Drawing.Imaging;

namespace QD.Utils
{
    /// <summary>
    /// 发送Web远程请求类
    /// </summary>
    public class WebHttpHelper
    {
       public static ICredentials Credentials = null;
       public static CookieContainer cookie = null;
       public static string Referer = "";
       public static string ContentType = "";
       public static string UserAgent = "";
       public static int TimeOut = 20000;
        
       public WebHttpHelper()
        {
            ContentType = string.Empty;
        }
         /// <summary>
        /// 发送Get远程请求，返回UTF-8编码的响应流
         /// </summary>
        /// <param name="url">格式：http://www,03you.com/login.aspx?username=test&pwd=123</param>
         /// <param name="html"></param>
         /// <returns></returns>
        public static string Request(string url)
        {
            return Request(url, "", "GET", System.Text.Encoding.UTF8);
        }
        public static string Request(string url, string param, System.Text.Encoding encoding)
        {
            return Request(url, param, "POST", System.Text.Encoding.UTF8);
        }
        /// <summary>
        /// 发送POST远程请求，返回UTF-8编码的响应流
        /// </summary>
        /// <param name="url"></param>
        /// <param name="param">post请求参数,格式如：UrlEncode("参数一")=UrlEncode("值一") &UrlEncode("参数二")=UrlEncode("值二")</param>
        /// <param name="html">请求返回值</param>
        /// <returns>错误消息</returns>
        public static string Request(string url, string param, string method, System.Text.Encoding encoding)
        {
            string html = "";
            HttpWebRequest myRequest = null;
            HttpWebResponse myResponse = null;
            Stream reqStream = null;
            StreamReader sRead = null;

            byte[] data = System.Text.Encoding.Default.GetBytes(param);
            try
            {
                //构造Web请求
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    myRequest = WebRequest.Create(url) as HttpWebRequest;
                    myRequest.ProtocolVersion = HttpVersion.Version10;
                }
                else
                    myRequest = (HttpWebRequest)WebRequest.Create(url);
                myRequest.Method = method;
                myRequest.KeepAlive = true;
                myRequest.ContentType = ContentType;
                myRequest.ContentLength = data.Length;
                myRequest.Timeout = TimeOut;
                myRequest.Referer = Referer;
                myRequest.UserAgent = UserAgent;

                myRequest.Headers.Add("Accept-Language", "zh-cn");
                if (cookie == null)
                    cookie = new CookieContainer();
                if (Credentials == null)
                    Credentials = CredentialCache.DefaultCredentials;

                myRequest.CookieContainer = cookie;
                myRequest.KeepAlive = true;
                myRequest.ServicePoint.Expect100Continue = false;

                //请求流,发送POST参数
                if (data.Length > 0)
                {
                    reqStream = myRequest.GetRequestStream();
                    reqStream.Write(data, 0, data.Length);
                    reqStream.Close();
                }
                //响应流
                myResponse = (HttpWebResponse)myRequest.GetResponse();
                sRead = new StreamReader(myResponse.GetResponseStream(), encoding);
                html = sRead.ReadToEnd();
            }
            catch (Exception ex)
            {
                html = "";
            }
            finally
            {
                if (sRead != null)
                    sRead.Close();

                if (reqStream != null)
                    reqStream.Close();

                if (myResponse != null)
                    myResponse.Close();

                if (myRequest != null)
                    myRequest.Abort();
            }
            return html;
        }

        public static string Request(string url, string param, string method, System.Text.Encoding encoding, out string returnUrl)
        {
            returnUrl = url;
            string html = "";
            HttpWebRequest myRequest = null;
            HttpWebResponse myResponse = null;
            Stream reqStream = null;
            StreamReader sRead = null;

            byte[] data = System.Text.Encoding.Default.GetBytes(param);
            try
            {
                //构造Web请求
                if (url.StartsWith("https", StringComparison.OrdinalIgnoreCase))
                {
                    ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                    myRequest = WebRequest.Create(url) as HttpWebRequest;
                    myRequest.ProtocolVersion = HttpVersion.Version10;
                }
                else
                    myRequest = (HttpWebRequest)WebRequest.Create(url);
                myRequest.Method = method;
                myRequest.KeepAlive = true;
                myRequest.ContentType = ContentType;
                myRequest.ContentLength = data.Length;
                myRequest.Timeout = TimeOut;
                myRequest.Referer = Referer;
                myRequest.UserAgent = UserAgent;

                myRequest.Headers.Add("Accept-Language", "zh-cn");
                if (cookie == null)
                    cookie = new CookieContainer();
                if (Credentials == null)
                    Credentials = CredentialCache.DefaultCredentials;

                myRequest.CookieContainer = cookie;
                myRequest.KeepAlive = true;
                myRequest.ServicePoint.Expect100Continue = false;
                myRequest.AllowAutoRedirect = true;
                //请求流,发送POST参数
                if (data.Length > 0)
                {
                    reqStream = myRequest.GetRequestStream();
                    reqStream.Write(data, 0, data.Length);
                    reqStream.Close();
                }
                //响应流
                myResponse = (HttpWebResponse)myRequest.GetResponse();
                sRead = new StreamReader(myResponse.GetResponseStream(), encoding);
                html = sRead.ReadToEnd();
                returnUrl = myResponse.ResponseUri.ToString();  //返回最后打开的网址
            }
            catch (Exception ex)
            {
                html = "";
            }
            finally
            {
                if (sRead != null)
                    sRead.Close();

                if (reqStream != null)
                    reqStream.Close();

                if (myResponse != null)
                    myResponse.Close();

                if (myRequest != null)
                    myRequest.Abort();
            }
            return html;
        }

        private static bool CheckValidationResult(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors errors)
        {
            return true; //总是接受 
        }

        public static string UpLoad(string url, string file, string paramName, string contentType, NameValueCollection nvc)
        {
            string result = string.Empty;
            string boundary = "---------------------------" + DateTime.Now.Ticks.ToString("x");
            byte[] boundarybytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");

            HttpWebRequest wr = (HttpWebRequest)WebRequest.Create(url);
            wr.ContentType = "multipart/form-data; boundary=" + boundary;
            wr.Method = "POST";
            wr.KeepAlive = true;
            wr.Credentials = System.Net.CredentialCache.DefaultCredentials;

            Stream rs = wr.GetRequestStream();

            string formdataTemplate = "Content-Disposition: form-data; name=\"{0}\"\r\n\r\n{1}";
            foreach (string key in nvc.Keys)
            {
                rs.Write(boundarybytes, 0, boundarybytes.Length);
                string formitem = string.Format(formdataTemplate, key, nvc[key]);
                byte[] formitembytes = System.Text.Encoding.UTF8.GetBytes(formitem);
                rs.Write(formitembytes, 0, formitembytes.Length);
            }
            rs.Write(boundarybytes, 0, boundarybytes.Length);

            string headerTemplate = "Content-Disposition: form-data; name=\"{0}\"; filename=\"{1}\"\r\nContent-Type: {2}\r\n\r\n";
            string header = string.Format(headerTemplate, paramName, file, contentType);
            byte[] headerbytes = System.Text.Encoding.UTF8.GetBytes(header);
            rs.Write(headerbytes, 0, headerbytes.Length);

            FileStream fileStream = new FileStream(file, FileMode.Open, FileAccess.Read);
            byte[] buffer = new byte[4096];
            int bytesRead = 0;
            while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
            {
                rs.Write(buffer, 0, bytesRead);
            }
            fileStream.Close();

            byte[] trailer = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            rs.Write(trailer, 0, trailer.Length);
            rs.Close();

            WebResponse wresp = null;
            try
            {
                wresp = wr.GetResponse();
                Stream stream2 = wresp.GetResponseStream();
                StreamReader reader2 = new StreamReader(stream2);
                result = reader2.ReadToEnd();
            }
            catch (Exception ex)
            {
                result = string.Empty;                
            }
            finally
            {
                if (wresp != null)
                {
                    wresp.Close();
                    wresp = null;
                }
                wr = null;
            }
            return result;
        }

        /// <summary>
        /// 下载远程图片保存到本地
        /// </summary>
        /// <param name="savedir">本地保存路径</param>
        /// <param name="imgpath">远程图片文件</param>
        /// <returns></returns>
        public static string DownRemoteImg(string savedir, string imgpath)
        {
            if (string.IsNullOrEmpty(imgpath))
                return string.Empty;
            else
            {
                string imgName = string.Empty;
                string imgExt = string.Empty;
                string saveFilePath = string.Empty;
                imgName = imgpath.Substring(imgpath.LastIndexOf("/"), imgpath.Length - imgpath.LastIndexOf("/"));
                imgExt = imgpath.Substring(imgpath.LastIndexOf("."), imgpath.Length - imgpath.LastIndexOf("."));

                saveFilePath = savedir;
                if (!Directory.Exists(saveFilePath))
                    Directory.CreateDirectory(saveFilePath);

                try
                {
                    WebRequest wreq = WebRequest.Create(imgpath);
                    wreq.Timeout = 10000;
                    HttpWebResponse wresp = (HttpWebResponse)wreq.GetResponse();
                    Stream s = wresp.GetResponseStream();
                    System.Drawing.Image img;
                    img = System.Drawing.Image.FromStream(s);
                    switch (imgExt.ToLower())
                    {
                        case ".gif":
                            img.Save(saveFilePath + imgName, ImageFormat.Gif);
                            break;
                        case ".jpg":
                        case ".jpeg":
                            img.Save(saveFilePath + imgName, ImageFormat.Jpeg);
                            break;
                        case ".png":
                            img.Save(saveFilePath + imgName, ImageFormat.Png);
                            break;
                        case ".icon":
                            img.Save(saveFilePath + imgName, ImageFormat.Icon);
                            break;
                        case ".bmp":
                            img.Save(saveFilePath + imgName, ImageFormat.Bmp);
                            break;
                    }

                    img.Dispose();
                    s.Dispose();

                    return savedir + imgName;
                }
                catch
                {
                    return "";
                }
            }
        }

    }
}